home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-03-19 | 34.2 KB | 1,056 lines |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 3D Library
- version 1.5 (release)
-
- by Steven Ludtke
-
- April 28, 1990
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- NOTICE
-
- The 3d library and all associated software in this distribution
- is Copyright 1990 by Steven J. Ludtke. You have permission to
- use and/or modify this code for any purpose commercial or non-
- commercial with two conditions : I must be given credit in any
- distributed product's documentation, and if any part of this
- package is used in any commercial product (even Shareware) one
- free copy of said software must be sent to me at the following
- address : Steven Ludtke, 406 Yale Cir., Glenwood Springs, CO
- 81601; all other royalties are waived. This Copyright notice
- must accompany any distributions of any part of this package,
- and in general, the package should be distributed intact, with
- no modifications. This notice must not be removed from the 3d.c,
- test.c, and cube.c source code in this release. Modified
- versions of this package may not be distributed without my
- consent. If the laws in your home state make any of the
- conditions in the disclaimer invalid, permission to use and
- distribute any part of this package in that state is withdrawn.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - 2 -
-
-
-
-
-
-
-
-
-
-
- Release Notes
- -------------
-
- Version 1.0 : The initial release. It used a very primitive
- sorting routine which proved to be insufficient for general
- hidden surface removal. It also did perspective views
- incorrectly, although it was not terribly obvious.
-
- Version 1.5 (beta) : It fixes the above bugs and
- adds an additional method for specifying viewing angles and
- positions. The simple sorting routine for hidden surface
- removal is still available, since it is much faster and
- will work in some cases. The new routine is used by default.
- Please mail bug reports to the address found at the end of the
- doc file. I've been busy, so assembly language will have to
- wait for the next version.
- The supplied makefile, etc ... is for Manx 5.0. It should
- work with Lattice, but I haven't tried it. It should also work
- with Manx 3.6 with appropriate makefile mods. I didn't use
- prototypes, but I did use precompiled include files. If you're
- not using Manx 5.0, you'll have to tack include.c to the top
- of 3d.c to get things to work.
-
- Version 1.5 (release) : A number of problems with the new
- surface sorting algorithm were found in beta testing. I fixed
- most of these, but eventually decided to take a new approach. A
- slightly improved version of the simple sorting routine is used
- in the package. The complex routine has been removed. A friend
- of mine wrote a 3d editor for files in the standard .3d file
- format I use. I included (with his permission) executable for
- this editor. It's pretty spiffy. A few new .3d files have also
- been included. Oh yeah, the Z axis points in the right direction
- now.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - 3 -
-
-
-
-
-
-
-
-
-
-
- Introduction
- ---------------------
-
- This library represents an attempt to provide the Amiga
- community with a high speed, easy to use 3d display library for
- C programmers. The library uses the transformation matrix
- method, which is the fastest method I know of doing 3d
- transformations while still providing relatively intuitive
- rotations. Integer arithmetic is used for speed. Additionally,
- the data is stored in a format that will make it easy to
- optimize the code in assembly language. I wrote the code for
- Aztec C (5.0), but I haven't converted anything to assembly
- language yet, so the current version should work with Lattice as
- well.
- A number of beta-testers used Lattice with the library with
- complete success. They said a few obvious changes were required,
- but other than that, everything went fine. (Be SURE to use the
- FFP library, not one of the double prec. libraries. There is a
- factor of 2 speed difference involved.)
- The library provides what I consider relatively high speed 3d
- displays. It can rotate and draw roughly 500 lines/second (with
- the FFP library). Once I've converted the rotation code to
- optimized assembly, I expect the time required for the
- calculation portion of the display to be reduced by at least a
- factor of 2. Surface drawing is somewhat slower, depending on a
- variety of factors. It is still reasonably fast.
- Since a number of the parameters used in the library are
- application specific, the 'library' is actually a C source file
- that you include in your program. This is done primarily for
- speed. If some of the parameters were variables rather than
- #defines, the library would run significantly slower. The code
- is relatively small, and it seems unlikely that more than one 3d
- application would be active at one time, so C source seems to me
- to be a reasonable way to go. If anyone has a better idea for
- future versions, I'd love to hear it.
-
- Included in this package are the following :
- 3d.c - The actual library code. This file is included in any
- program you use the 3d routines in. It must appear in
- the correct place in your program. Read the instr. or
- look at one of the sample programs for more info.
- include.c- used to precompile all standard includes. Otherwise
- put at the beginning of 3d.c.
- 3d.doc - This file.
- makefile - An Aztec 5.0 makefile for the two sample programs.
- cube.c - A sample program that does double buffered animation
- of a cube moving around. There is a reason it doesn't
- move very smoothly. Look at the code before you think
- that's the best the library can do.
- test.c - A sample program that allows you to display 3d files
- that are in a standard (non-IFF) format. Several
- sample files are included. Look at the source for
- instructions.
-
-
- - 4 -
-
-
-
-
-
-
-
-
-
-
- *.3d - Various files of 3d data (non-IFF) for use with test.c
- maze.3d - This example contains a large 'floor' that won't sort
- correctly with filled surfaces. It is an example of
- what NOT to do.
- earth.3d- This example contains non-planar surfaces. You'll note
- that it won't work well with the complex sorting
- routine (it does work with the simple one,though).
- edit - A 3d editor written by a friend of mine. No source is
- included with this release. He compiled it with
- Lattice, and I think he might have used a double prec.
- math library. This could slow it down a bit more than
- is necessary.
- edit.doc- Docs for the editor.
-
- The two sample programs were written for Aztec C ver 5.0. A
- few changes are necessary to use them with Lattice, but they
- will work.
-
- Hopefully most of the bugs have been worked out by now. If you
- do find a bug (or have some questions), please let me know so I
- can try to fix it.
-
- I can be contacted via any of the following :
- stevel@tybalt.caltech.edu (until June 90)
- stevel@citiago.bitnet (until June 90)
- gluon@theta.caltech.edu
- 72335,1537 (compuserve)
- Steve Ludtke, 1-54 Caltech, Pasadena CA 91126 (until June 90)
- Steve Ludtke, 406 Yale Cir, Glen. Spgs. CO 81601 (after that)
-
- My current plans for the next version are as follows :
- 1. Convert much of the code to assembly for speed.
- 2. Perhaps I'll try to add some primitive shading routines
- (simple lighting effects).
- 3. More complete x-specs support ???
- 4. A more intelligent surface sorting routine (faster).
- 5. Some object oriented routines to sit on top of the current
- library.
- 6. Anything you suggest ...
-
- Please talk to me. I like to get mail. Btw, this code should
- be pretty easy to convert for use on other machines. All you
- really need to change is the actual graphics function calls.
-
-
-
-
-
-
-
-
-
-
-
-
- - 5 -
-
-
-
-
-
-
-
-
-
-
- Here's the actual programming info. Info on structures follows
- the function information. I tried to make it as easy to use as
- possible.
-
- Before your try to write your own code, you should probably
- look at one of the examples. I'll summarize the basic steps in
- using the library here :
-
- Before the #include "3d.c" statement, you need to have several
- #define statements in you program. If necessary you can replace
- some of the defines with global variables, but you should avoid
- this as it will slow the program down. The defines you need are
- as follows :
-
- #define D3VDIST 256 <- This is the distance from the
- observer to the vanishing point. It
- is only used with rotatev(), and
- rotatevp(). Please read about it.
- #define REZ 1024 <- Since the program uses integer
- math, it must use several bits
- for fractional calculations. 1024
- would give 3 digits of accuracy. This
- number needs to be a power of 2 for
- upward compatibility. In general it
- should be roughly as large as the
- # of pixels in the display you use.
- The larger it is, the smaller your
- space for points is. REZ=1024 leaves
- you with 20 bits for each of: x,y,z.
- #define XCEN 250 <- This is the x coord (in the bitmap)
- of the center (x=0) coordinate for 3d
- displays.
- #define YCEN 100 <- Same for y coord.
- #define XHI 600 <- This is the highest x value in your
- bitmap. Anything above this will be
- clipped by the drawing routines.
- #define YHI 180 <- Same for y.
- #define XLO 0 <- Low x clipping value.
- #define YLO 0 <- Low y clipping value.
- #define ASPECT 23/10 <- This is the aspect ratio used to
- insure a square coord system on the
- screen. 23/10 is correct for 640X200
- mode. Obviously 11/10 should be used
- in 320X200 mode.
- #include "3d.c"
-
-
-
- Now, set up a VECTOR structure. You'll need to get free memory
- for all 6 arrays it points to. Set up a LINES structure with
- sufficient memory, too. Once, this is done, you can load your 3d
- data into the structures.
- Now set up a window or screen (something with a valid
- RastPort), or two for double buffering, or four for double
-
- - 6 -
-
-
-
-
-
-
-
-
-
-
- buffered x-specs displays. If you intend to use d3surf(), call
- Init3Ras() with all your RastPorts.
- Now SetDrMd() for all RastPorts. If you don't have color data
- in your LINES structure, also do a SetAPen() and a SetOPen()
- (for surfaces) for all RastPorts.
- Now you can actually display data. setxfm() or setxfm2() can
- be used to set the viewpoint for the display. rotatev(),
- rotate(), rotatep(), or rotatevp() can be used to actually
- perform the rotations with or without perspective. d3surf() and
- d3lines() can then be used to render the data in a RastPort.
- When you're all done, don't forget to call Exit3d() if you
- called Init3Ras(). DON'T call it if you only used d3lines().
- Simple huh ??? : )
-
- No real x-specs support code is provided in this release. You
- still have to set up the code to drive the glasses yourself.
- This library is ideal, however, for doing the actual drawing.
- Just pick a point the person is looking at, then set up two
- viewing positions, one for each eye. This should be quite easy
- using the setxfm2() routine.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - 7 -
-
-
-
-
-
-
-
-
-
-
-
- FUNCTION DEFINITIONS :
-
- setxfm - Set rotation and translation values for next xform.
-
- USAGE :
- setxfm(a1,a1,a3,x,y,z,m,d)
- double a1,a2,a3;
- long x,y,z,m,d;
-
- FUNCTION :
- This routine sets transformation matrix values based on the
- parameters you pass it. The actual matrix is a global array,
- however for upward compatibility's sake, you shouldn't access it
- except through this routine.
-
- INPUTS :
- The three parameters, 'a1-a3' are rotation angles in radians
- (see the description of rotations following the structure
- definitions). 'x','y','z' are translation parameters. Since
- positional values are integral, the translation values must also
- be integral.
- 'n' and 'd' are scaling factors. Since integer arithmetic is
- used, a fraction is used for the scaling factor. 'n' is the
- numerator and 'd' is the denominator of the scaling factor. The
- way this is implemented, it doesn't slow the translations down,
- so if you don't need it just set 'n' and 'd' to 1. It will be
- just like they didn't exist.
-
- OUTPUTS :
- None.
-
- ---------------------------------------
- setxfm2 - Set rotation and translation values for next xform.
-
- USAGE :
- setxfm(x,y,z,dx,dy,dz,m,d)
- long x,y,z,dx,dy,dz,m,d;
-
- FUNCTION :
- This routine sets transformation matrix values based on the
- parameters you pass it. The actual matrix is a global array,
- however for upward compatibility's sake, you shouldn't access it
- except through this routine.
- The only difference between this routine and setxfm() is how
- the viewing angle is specified. rotatep() or rotatevp() is
- normally used with this routine.
- INPUTS :
- 'x','y', and 'z' are translation factors, just like those
- used in setxfm(). If rotatep() or rotatevp() is used, these
- variables are used to specify the location of the viewer.
- 'dx','dy', and 'dz' are then used to specify viewing
- direction. These variables define a vector pointing in the
- direction to be looked in. The length of this vector affects
-
- - 8 -
-
-
-
-
-
-
-
-
-
-
- nothing. Z will always be upwards on the screen, unless looking
- straight up or straight down. For example, a viewer at (-10,-
- 10,-10) looking towards the origin would be defined by :
- setxfm2(-10,-10,-10,10,10,10,n,d).
- 'n' and 'd' are scaling factors. Since integer arithmetic is
- used, a fraction is used for the scaling factor. 'n' is the
- numerator and 'd' is the denominator of the scaling factor. The
- way this is implemented, it doesn't slow the translations down,
- so if you don't need it just set 'n' and 'd' to 1. It will be
- just like they didn't exist.
-
- OUTPUTS :
- None.
-
- ---------------------------------------
- rotate - Rotates an array of vectors using the current setxfm()
- vals without perspective.
-
- USAGE :
- rotate(v,n)
- VECTOR *v;
- int n;
-
- FUNCTION:
- This routine actually performs the translation of a group of
- points in 3-space based on the parameters set by setxfm().
-
- INPUTS :
- 'v' points to a vector structure which must be initialized with
- pointers to all 6 arrays of size >='n'. The first 'n' vectors
- will be rotated. Note that the 'x','y','z' VECTOR values are
- unchanged. These values are transformed, and the results are
- stored in 'tx','ty','tz'. If you wish to transform a subset of
- the points, a separate VECTOR structure pointing to the
- beginning of the subset can be used.
-
- OUTPUTS:
- none.
-
- ---------------------------------------
- rotatev - Rotates an array of vectors using the current setxfm
- vals with perspective.
-
- USAGE :
- rotatev(v,n)
- VECTOR *v;
- int n;
-
- FUNCTION:
- This routine actually performs the translation of a group of
- points in 3-space based on the parameters set by setxfm(). The
- only difference between this routine and rotate() is the
- addition of perspective.
-
-
- - 9 -
-
-
-
-
-
-
-
-
-
-
- INPUTS :
- 'v' points to a vector structure which must be initialized with
- pointers to all 6 arrays of size >='n'. The first 'n' vectors
- will be rotated. Note that the 'x','y','z' VECTOR values are
- unchanged. These values are transformed, and the results are
- stored in 'tx','ty','tz'. If you wish to transform a subset of
- the points, a separate VECTOR structure pointing to the
- beginning of the subset can be used.
-
- OUTPUTS:
- none.
-
- ---------------------------------------
- rotatep - Rotates an array of vectors using the current setxfm
- vals.
-
- USAGE :
- rotatep(v,n)
- VECTOR *v;
- int n;
-
- FUNCTION:
- This routine actually performs the translation of a group of
- points in 3-space based on the parameters set by setxfm(). The
- only difference between this routine and rotate() is that
- translations are done before, not after rotations. This makes
- this routine work correctly with setxfm2().
-
- INPUTS :
- See rotate()
-
- OUTPUTS:
- none.
- ---------------------------------------
-
- rotatevp - Rotates an array of vectors using the current setxfm
- vals with perspective.
-
- USAGE :
- rotatev(v,n)
- VECTOR *v;
- int n;
-
- FUNCTION:
- This routine actually performs the translation of a group of
- points in 3-space based on the parameters set by setxfm(). The
- only difference between this routine and rotatev() is that
- translations are perfomed before, not after rotations. This
- routine should be used with setxfm2().
-
- INPUTS :
- See rotatev()
-
- ---------------------------------------
-
- - 10 -
-
-
-
-
-
-
-
-
-
-
-
- Init3Ras - Sets a rastport up for area fills.
-
- USAGE:
- Init3Ras(rp,rp2,rp3,rp4)
- struct RastPort *rp,*rp2,*rp3,*rp4;
-
- FUNCTION:
- This routine should be called once for each RastPort to be used
- with d3surf(). If it is called more than once with the same
- RastPort it could cause serious problems. This routine only
- needs to be called if d3surf() is going to be used. If only
- d3lines() is going to be used, you can save some memory by not
- calling this routine.
-
- INPUTS:
- 'rp'-'rp4' point to RastPorts which will be used with d3surf().
- d3surf uses area fill operations, so the RastPort it uses must
- be given temporary storage for use in the filling. 'rp2'-'rp4'
- should be set to NULL if only one RastPort is to be used. If
- both are passed, they will be assigned the same temporary
- storage area, thus saving a significant amount of memory.
- This routine allows multiple rastports for use in double-
- buffering and x-specs. If double-buffered, x-specs animation is
- performed, 4 screens will be required.
-
- OUTPUTS:
- None.
- ---------------------------------------
- Exit3d - Frees up the memory allocated by Init3Ras.
-
- USAGE :
- Exit3d(rp)
- struct RastPort *rp;
-
- FUNCTION:
- This routine frees up the memory allocated by Init3Ras().
-
- INPUTS:
- 'rp' points to a RastPort initialized with Init3Ras(). If 2 or
- more RastPorts were initialized with a SINGLE call to
- Init3Ras(), only ONE of them should be passed to Exit3d(), and
- none should be used with area fills again.
- I should explain this in more detail. If two RastPorts are
- initialized with a single Init3Ras() call, both RastPorts will
- point to the same scratch memory area. Exit3d() frees this
- memory up. After you call it for one of the two RastPorts, the
- other one will point to an unallocated area in memory. If a fill
- operation is done at this time, it can cause all sorts of nasty
- problems. Be warned.
-
- OUTPUTS:
- None.
-
-
- - 11 -
-
-
-
-
-
-
-
-
-
-
- ---------------------------------------
- d3lines - Draw a group of lines connecting points in 3 space.
-
- USAGE:
- d3lines(vector,line,n,rp)
- VECTOR *vector;
- LINES *line;
- int n;
- struct RastPort *rp;
-
- FUNCTION:
- This routine actually draws lines connecting one or more points
- in 3-space. See the information on the VECTOR and LINES
- structures for more info.
-
- INPUTS:
- 'vector' points to a VECTOR structure with information on the
- points to be used in the line drawing. 'line' points to an array
- of LINES structures which contains a description of how the
- lines are to be drawn. 'n' is the number of elements in the
- array pointed to by 'line'. 'rp' points to the RastPort where
- the lines should be drawn.
-
- OUTPUTS:
- none.
-
- ---------------------------------------
- d3surf - Draw a group of surfaces in 3 space.
-
- USAGE:
- d3lines(vector,line,n,rp)
- VECTOR *vector;
- LINES *line;
- int n;
- struct RastPort *rp;
-
- FUNCTION:
- This routine is just like d3lines(), except filled polygons are
- drawn rather than lines. The polygons are sorted before drawing,
- so hidden line removal is accomplished. PLEASE READ ABOUT HIDDEN
- LINE REMOVAL BELOW.
-
- INPUTS:
- 'vector' points to a VECTOR structure with information on the
- points to be used in the surface drawing. 'line' points to an
- array of LINES structures which contains a description of how
- the surfaces are to be drawn. 'n' is the number of elements in
- the array pointed to by line. 'rp' points to the RastPort where
- the surfaces should be drawn.
-
- OUTPUTS: none.
-
-
-
-
- - 12 -
-
-
-
-
-
-
-
-
-
-
- STRUCTURES :
-
- VECTOR ->
- long *x,*y,*z;
- long *tx,*ty,*tz;
-
- This structure points to the data for all the vertices that
- are transformed. 'x','y','z' are arrays with the untransformed
- vertex information. 'tx','ty','tz' are arrays which contain the
- transformed equivalents of the vertices. 'tx','ty','tz' are
- filled in by rotate() and rotatev(). They must be initialized to
- point to sufficiently large areas of free memory by the user.
- The 'x','y','z' values represent vertical pixels on the
- screen. ie - the point (10,1,10) without perspective would
- appear 10 pixels below and 23 pixels to the right of the defined
- center (using a 23/10) aspect ratio.
- -----------------------------------------
-
- LINES ->
- unsigned short l;
- unsigned short nl : 1,nc : 1, nco : 1;
-
- For those of you not familiar with the above notation, nl, nc,
- and nco are 1 bit integers allocated within a single unsigned
- short. An array of LINES structures contains the information for
- line/polygon drawing. The fact that 'l' is allocated as a short
- means that you can't have more than 2^16 vertices in any single
- array. Hopefully this won't present any problems.
- The array of LINES should be used as follows :
- 'l' contains a vertex number in a VECTOR structure or a color
- (see below).
-
- 'nl' is set if this vertex is the beginning of a new
- line/polygon.
-
- 'nc' is set if 'l' represents a new fill color for polygons.
-
- 'nco' is set if 'l' represents a new outline color for polygons,
- or a new line color for line drawing.
-
- If filled shapes are to be drawn, not just lines, be sure to
- start a new line for each new polygon. That is, don't draw two
- filled shapes with one continuous line. This would look fine
- with d3lines(), but would produce strange effects with d3surf().
- Make sure all filled shapes are planar. The new surface sorting
- routine requires all surfaces to be planar. Incorrect sorting
- may occur if non-planar shapes are drawn.
- Color changes with d3lines() may occur anywhere. However,
- color changes used with d3surf() must occur only immediately
- after a nl=1 element. This is due to the way hidden line removal
- works. Every nl=1 element is taken to be the beginning of a new
- polygon. These polygons are then sorted so the farthest ones are
- drawn first. Color changes occurring before a nl=1 point will be
- attached to the wrong polygon when they are sorted. Color
-
- - 13 -
-
-
-
-
-
-
-
-
-
-
- changes in the middle of the shape may not have the desired
- effect (after 1 or more lines have been added).
-
- Here is a sample LINES array to make this all more clear :
-
- l nl nc nco
- 0 0 1 0 0 <- Starts a shape, vertex 0
- 1 2 0 0 1 <- Changes to outline color 2
- 2 1 0 1 0 <- Changes to filled color 1
- 3 1 0 0 0
- 4 2 0 0 0
- 5 3 0 0 0
- 6 0 0 0 0 <- Closes the shape, not necessary
- for d3surf().
- 7 3 0 0 1 <- Changes outline color. This is
- fine for d3lines(), but won't
- change correctly for d3surf().
- 8 4 1 0 0 <- New shape
- 9 5 0 0 0
- 10 6 0 0 0 <- No color was defined after the
- new shape started, so the color
- from the last drawn shape will
- be used. The shape is not
- closed. d3surf() will close the
- shape anyway. d3lines won't.
-
- In the above example, 0-6 will draw a quadrilateral in color 2
- if d3lines() is used. It will draw a filled quad., filled with
- color 1 and outlined in color 2, if d3surf() is used.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - 14 -
-
-
-
-
-
-
-
-
-
-
- ROTATIONS, AND HOW THEY'RE DONE
- -------------------------------
- This program uses a very standard scheme for rotating objects
- which is completely general. That is, you can observe your
- 'scene' from absolutely any imaginable perspective (within the
- bounds of integer math).
- The axes are set up as follows :
-
- Z| / Y
- | /
- | /
- |/
- -------------
- X
-
- That is, the X axis is the screen x axis, the Z axis is the
- screen y axis, and the Y axis goes positive into the screen.
-
- Rotations (for setxfm) are defined in terms of three steps.
- 'a1' defines a rotation angle from the X axis in the X-Y plane.
- 'a2' then rotates the specified number of radians away from the
- Z axis in the Y-Z plane. Finally 'a3' defines a rotation in
- radians from the new (rotated) X axis in the new X-Y plane.
- Explained another way : Say the ground is in the X-Y plane, ie
- going into the screen. 'a1' would spin an object resting on the
- ground as if it were a top. 'a2' would cause this rotated object
- to tilt on the screen, just like the Aster*ids spaceship spins.
- 'a3' would take the tilted object and spin it along the tilted
- plane. a3 is a bit hard to picture, play with it.
- I know this is somewhat complex, but you can do any possible
- rotation with it once you get the hang of it. It may also be
- easier to visualize if you picture the observer moving, rather
- than the object being rotated. I may try to add a few other
- schemes in the next version. We'll see what I can find.
- For those of you who are interested you can see how this
- transformation works in "Classical Mechanics" by Goldstein on
- page 146. (What can I say, I'm a physics major.)
- The new setxfm2() routine uses the same translation scheme as
- above. It simply converts the information you give it to
- setxfm() form. a3 is always set to 0.
- To display shapes from setxfm2() as explained, rotatep() or
- rotatevp() must be used. These routines perform the translation
- operation before the rotation operation. That is, they are
- designed to be used with a viewer that is moving around in 3-
- space, rather than a fixed viewer with moving objects. (objects
- can always be moved by changing their 'x','y','z' coords before
- a call to rotate). For the record, it would have been possible
- to implement this with the old rotate routines, but the new
- routines should do it a little faster.
-
-
-
-
-
-
- - 15 -
-
-
-
-
-
-
-
-
-
-
- Hidden Surface Removal
- ----------------------
- This has been the single biggest headache in the development
- of this library. Ver 1.5(beta) included an 'improved' routine
- that would do hidden surface removal perfectly with any set of
- planar shapes. Unfortunately, there was quite a lot of overhead
- in this routine, and I found it unbearably slow. I also never
- got it working 100% (I did get close). Eventually I got fed up
- and decided to do things the fast, but less friendly, way.
- An improved simple sorting routine is used in the release
- version. It sorts surfaces (planar surfaces are still pretty
- necessary) by doing a quicksort on the average y position of
- each surface. It is quite speedy, but it has a number of
- limitations.
- This routine will work fine as long as you restrict yourself
- so all surfaces that are close together are roughly the same
- size. If you need to make very large surfaces near very small
- surfaces, break the large one up into several smaller ones.
- Large, strange shapes, like the floor in maze.3d will cause
- problems. (that's why I included maze.3d)
- Essentially, the way to do high speed display of a series of
- 3d objects is to separate objects (groups of surfaces), sort the
- objects, then sort the surfaces within the object. As long as
- objects don't overlap in strange ways, this is the way to go.
- So, what you should do is set up several different LINES
- structures (all points can go in one VECTOR structure). Each
- LINES structure will contain data for one 'object'. Sort the
- objects yourself, then call d3surf for each.
-
- I plan to write a set of object oriented routines that will
- sit on top of the present library and make the above process
- more automatic. I hope to support routines like new_object(),
- add_surface(), move_object(), draw_object(), draw_objects(), etc
- ... This should make the library considerably more user
- friendly (if I find time to do it in the near future).
- ---------
-
- Again, if you run into any bugs or problems please let me
- know. Also keep in mind that, while you may feel free to modify
- this code, you might have upward compatibility problems if you
- do. I tried to comment the code a little for those of you who
- feel like making changes. Have fun !!!
-
-
-
-
-
-
-
-
-
-
-
-
-
- - 16 -
-
-
-
-
-